package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"

	"juzipi.cc/sfs"
)

func read(f io.Reader, size int) []byte {
	buffer := make([]byte, size)

	n, err := f.Read(buffer)
	if err == io.EOF {
		return nil
	}

	if err != nil {
		fmt.Println(err)
		return nil
	}

	return buffer[0:n]
}

func uploadFile(request *http.Request) {
	request.ParseMultipartForm(1024 * 1024 * 100)
	if request.Method == "POST" && request.MultipartForm != nil && request.MultipartForm.File != nil && request.MultipartForm.File["file"] != nil {
		f, h, e := request.FormFile("file")
		if e == nil {
			addr := "." + request.URL.Path
			if !strings.HasSuffix(addr, "/") {
				addr = addr + "/"
			}
			addr = addr + h.Filename
			fmt.Println("文件上传:", addr)
			file, e := os.Create(addr)
			if e != nil {
				fmt.Println(e.Error())
			} else {
				for {
					buff := read(f, 1024)
					if buff != nil {
						file.Write(buff)
					} else {
						break
					}
				}
				file.Close()
			}

		} else {
			fmt.Println(e.Error())
		}
	}
}

type serve struct{}

var allawyUpload = true

func (serve) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
	}()

	if request.URL.Path == "/favicon.ico" {
		return
	}

	if allawyUpload {
		uploadFile(request)
	}

	if strings.HasSuffix(request.URL.Path, "/") {
		fmt.Println("读取文件夹", request.URL.Path)

		view := sfs.BuildDirectoryView(request.URL.Path, allawyUpload)
		response.Write([]byte(view))
		return
	}

	fmt.Println("read file ", "."+request.URL.Path)

	if strings.HasSuffix(request.URL.Path, "apk") {
		response.Header().Set("Content-Type", "application/vnd.android.package-archive apk")
	}

	file, e1 := os.Open("." + request.URL.Path)
	if e1 != nil {
		response.WriteHeader(500)
		response.Write([]byte(e1.Error()))
		return
	}

	for {
		buff := read(file, 1024)
		if buff != nil {
			stat, _ := file.Stat()
			response.Header().Add("Content-Length", fmt.Sprintf("%d", stat.Size()))
			response.Write(buff)
		} else {
			break
		}
	}

	file.Close()
}

func main() {

	var ips []sfs.IP = sfs.GetIP()

	port := ":8999"
	args := os.Args
	for i, v := range args {
		if v == "-p" {
			port = ":" + args[i+1]
		}

		if v == "-disableUpload" {
			allawyUpload = false
		}

		if v == "-h" || v == "--help" {
			sfs.Help()
			return
		}
	}

	fmt.Println("Please visit in your browser:")
	for _, ip := range ips {
		fmt.Println(ip.Net, "  ", "http:"+ip.Addr+port+"/")
	}

	err := http.ListenAndServe(port, serve{})
	if err != nil {
		fmt.Println(err.Error())
	}
}
